package org.afs.gescol.gwt.client.presenter;

import java.util.Map;

import org.afs.gescol.gwt.client.factory.AppClientFactory;
import org.afs.gescol.gwt.client.service.EleveServicesGwt;
import org.afs.gescol.gwt.client.service.EleveServicesGwtAsync;
import org.afs.gescol.gwt.client.service.GetServicesGwt;
import org.afs.gescol.gwt.client.util.ConstantesKeys;
import org.afs.gescol.gwt.shared.EleveDetailsModel;
import org.scub.foundation.framework.gwt.module.client.mvp.management.error.ErrorEvent;
import org.scub.foundation.framework.gwt.module.client.mvp.management.loading.LoadingEvent;
import org.scub.foundation.framework.gwt.module.client.mvp.presenter.Presenter;
import org.scub.foundation.framework.gwt.module.client.mvp.view.View;
import org.scub.foundation.framework.gwt.module.client.util.composants.suggestbox.SuggestListBoxSingle;
import org.scub.foundation.framework.gwt.module.client.util.composants.suggestbox.SuggestListBoxSuggestEvent;
import org.scub.foundation.framework.gwt.module.client.util.composants.suggestbox.SuggestListBoxSuggestEventHandler;
import org.scub.foundation.framework.gwt.module.shared.IdLabelModel;

import com.github.gwtbootstrap.client.ui.Button;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets.ForIsWidget;

public class ElevePresenter extends Presenter {

    private EleveServicesGwtAsync eleveServices = EleveServicesGwt.App.getInstance();

    private EleveView view = AppClientFactory.getEleveView();

    private Map<String, IdLabelModel> constantes;

    private Long id;

    private SuggestListBoxSuggestEventHandler<IdLabelModel> slbEventHandler = new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
        @Override
        public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
            GetServicesGwt.App.getInstance().getPeriodeByAnnee(constantes.get(ConstantesKeys.OPENED_YEAR_KEY).getId(), event.getCallBack());
        }
    };

    public enum PANELS_ELEVE_KEYS {
        IDENTITE, PARENTS, ABS_PERM, FRAIS_SCO, NOTE_BUL, PARCOURS
    }

    private void depilerBtnBinding() {
        final Map<PANELS_ELEVE_KEYS, Button> mapBtn = view.getBtnDeplier();
        for (final PANELS_ELEVE_KEYS key : PANELS_ELEVE_KEYS.values()) {
            final Button btn = mapBtn.get(key);
            if (btn != null) {
                btn.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        view.deplier(key);
                    }
                });
            }
        }
    }

    private void slbPeriodeBinding() {
        final Map<PANELS_ELEVE_KEYS, SuggestListBoxSingle<IdLabelModel>> mapSlb = view.getSlbPeriode();
        for (final PANELS_ELEVE_KEYS key : PANELS_ELEVE_KEYS.values()) {
            final SuggestListBoxSingle<IdLabelModel> slb = mapSlb.get(key);
            if (slb != null) {
                slb.addSuggestHandler(slbEventHandler);
            }
        }
    }

    private void initSlbPeriode() {
        final Map<PANELS_ELEVE_KEYS, SuggestListBoxSingle<IdLabelModel>> mapSlb = view.getSlbPeriode();
        for (final PANELS_ELEVE_KEYS key : PANELS_ELEVE_KEYS.values()) {
            final SuggestListBoxSingle<IdLabelModel> slb = mapSlb.get(key);
            if (slb != null) {
                slb.setValue(constantes.get(ConstantesKeys.OPENED_PERIOD_KEY));
            }
        }
    }

    public void loadData(Long id) {
        this.id = id;
        fireEventGlobalBus(new LoadingEvent(true));
        eleveServices.getEleveById(id, new AsyncCallback<EleveDetailsModel>() {
            @Override
            public void onSuccess(EleveDetailsModel result) {
                view.clearPanel(PANELS_ELEVE_KEYS.IDENTITE);
                view.clearPanel(PANELS_ELEVE_KEYS.PARENTS);
                view.clearPanel(PANELS_ELEVE_KEYS.ABS_PERM);
                view.clearPanel(PANELS_ELEVE_KEYS.FRAIS_SCO);
                view.clearPanel(PANELS_ELEVE_KEYS.NOTE_BUL);
                view.clearPanel(PANELS_ELEVE_KEYS.PARCOURS);
                view.load(result, constantes, PANELS_ELEVE_KEYS.IDENTITE);
                view.load(result, constantes, PANELS_ELEVE_KEYS.PARENTS);
                view.load(result, constantes, PANELS_ELEVE_KEYS.ABS_PERM);
                view.load(result, constantes, PANELS_ELEVE_KEYS.FRAIS_SCO);
                view.load(result, constantes, PANELS_ELEVE_KEYS.NOTE_BUL);
                view.load(result, constantes, PANELS_ELEVE_KEYS.PARCOURS);
                initSlbPeriode();
                fireEventGlobalBus(new LoadingEvent(false));
            }
            
            @Override
            public void onFailure(Throwable caught) {
                fireEventGlobalBus(new LoadingEvent(false));
                fireEventGlobalBus(new ErrorEvent(caught));
            }
        });
    }

    @Override
    public void onShow(ForIsWidget container) {
        container.add(view.asWidget());
    }

    @Override
    public void onDetach() {
        // TODO Auto-generated method stub

    }

    @Override
    public void onBind() {
        depilerBtnBinding();
        slbPeriodeBinding();
        view.getSlbClasse().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getClassByName(event.getSuggest(), event.getCallBack());
            }
        });
        view.getSlbRedoublant().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getOuiNon(event.getSuggest(), event.getCallBack());
            }
        });
        view.getSlbStatut().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getStatutByName(event.getSuggest(), event.getCallBack());
            }
        });
        view.getSlbSexe().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getGenreByTypePersonne(HomePresenter.ID_TYPE_ELEVE, event.getSuggest(), event.getCallBack());
            }
        });
    }

    @Override
    public void initView() {
        view.init();
    }

    /**
     * Get the value of constantes.
     * @return the constantes
     */
    public Map<String, IdLabelModel> getConstantes() {
        return constantes;
    }

    /**
     * Set the value of constantes.
     * @param constantes the constantes to set
     */
    public void setConstantes(Map<String, IdLabelModel> constantes) {
        this.constantes = constantes;
    }

    /**
     * Eleve view interface.
     */
    public interface EleveView extends View {

        /**
         * Get the button to unfold panel.
         * @return the button map
         */
        Map<PANELS_ELEVE_KEYS, Button> getBtnDeplier();

        /**
         * Get the slb on the all panel.
         * @return the slb map
         */
        Map<PANELS_ELEVE_KEYS, SuggestListBoxSingle<IdLabelModel>> getSlbPeriode();

        /**
         * Get the slb.
         * @return the slb
         */
        SuggestListBoxSingle<IdLabelModel> getSlbClasse();

        /**
         * Get the slb.
         * @return the slb
         */
        SuggestListBoxSingle<IdLabelModel> getSlbRedoublant();

        /**
         * Get the slb.
         * @return the slb
         */
        SuggestListBoxSingle<IdLabelModel> getSlbSexe();

        /**
         * Get the slb.
         * @return the slb
         */
        SuggestListBoxSingle<IdLabelModel> getSlbStatut();

        /**
         * To fold/unfold a panel.
         * @param key the panel key
         */
        void deplier(PANELS_ELEVE_KEYS key);

        /**
         * Fill the data on the view.
         * @param eleve the detailed data on eleve
         * @param constantes the constantes
         * @param key the panel key
         */
        void load(EleveDetailsModel eleve, Map<String, IdLabelModel> constantes, PANELS_ELEVE_KEYS key);

        /**
         * Clear a panel on the view.
         * @param key the panel key
         */
        void clearPanel(PANELS_ELEVE_KEYS key);
    }

}
